/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package vadung.contragame2d;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author dung.voanh
 */
public class GameContraCanvas extends Canvas
        implements Runnable {
    // Member attribute
    //-----------------
    private boolean m_isGameRunning = true;
    private long m_lGameTimeLastUpdate;
    private int m_iKeyPressAction = 0;
    // Graphics for game
    //private Image m_imgGraphics;
    private Graphics m_graGame;
    // Current State is working
    private int m_iCurrentState;
    private boolean m_isExitCurrentState;
    // State int game
    private StateLogo m_stateLogo;
    private StateSplash m_stateSplash;
    private StateMainMenu m_stateMainMenu;
    private StateNewGame m_stateNewGame;
    private StateConfirmMenu m_statecConfirmMenu;
    
    
    public Graphics getGraphics() {
        return m_graGame;
    }

    public long GetGameTimeLastUpdate() {
        return m_lGameTimeLastUpdate;
    }

    public int GetKeyPressAction() {
        return m_iKeyPressAction;
    }

    public int GetCurrentState() {
        return m_iCurrentState;
    }
    
    public GameContraCanvas() {
        //m_imgGraphics = Image.createImage(getWidth(), getHeight());
        //m_graGame = m_imgGraphics.getGraphics();        
        Init();
    }

    private void Init() {
        // Loadi resource manager
        ResourceManager.GetInstance().Load("/SM.txt");
        // Init SoundManager
        SoundManger.GetInstance().Init();
        
        // Init state machine
        this.StateMachine_Init();
        
    }

    public void AddKeyAction(int keyGame) {
        m_iKeyPressAction |= keyGame;
    }

    public void RemoveKeyAction(int keyGame) {
        m_iKeyPressAction &= ~keyGame;
    }

    public void Start() {
        m_lGameTimeLastUpdate = System.currentTimeMillis();
        Thread threadStartGame = new Thread(this);
        threadStartGame.start();
    }

    public void Exit() {
        m_isGameRunning = false; // Stop thread run game  
        //m_isExitCurrentState = true;
        //Save game...
        try {
            m_stateNewGame.SaveGame();
        } catch (Exception e) {
        }
        
        SoundManger.GetInstance().Stop();
        MyObject.GetInstance().ClearAll();
        Midlet.s_midlet.notifyDestroyed();
    }

    protected void Update() {
        this.StateMachine_Update();
    }

    protected void paint(Graphics g) {
        m_graGame = g;
        m_graGame.setColor(0);
        m_graGame.fillRect(0, 0, getWidth(), getHeight());
        //Draw objects in game
        this.StateMachine_Render();
        //Draw m_imgGraphics of game to canvas
        //g.drawImage(m_imgGraphics, 0, 0, Graphics.TOP|Graphics.LEFT);
    }

    public void run() {
        long lCurrentTime;
        long lDeltaTime;

        while (m_isGameRunning) {
            lCurrentTime = System.currentTimeMillis();
            lDeltaTime = lCurrentTime - m_lGameTimeLastUpdate;
            if (lDeltaTime < DEFINE.TIME_PER_FRAME) {
                try {
                    Thread.sleep(DEFINE.TIME_PER_FRAME - lDeltaTime);
                } catch (InterruptedException ex) {
                    //ex.printStackTrace();
                }
            }

            Update();
            repaint();
            m_lGameTimeLastUpdate = System.currentTimeMillis();

            //System.out.println("Loop frame game...");
        }
    }

    //------------------------------------------------------------------------//
    //----------------------------------State Machine-------------------------//
    //------------------------------------------------------------------------//
    public void StateMachine_Init() {
        m_isExitCurrentState = true;
        m_stateLogo = new StateLogo();
        m_stateMainMenu = new StateMainMenu();
        m_stateSplash = new StateSplash(); 
        m_stateNewGame = new StateNewGame();
        m_statecConfirmMenu = new StateConfirmMenu();
    }

    public void StateMachine_Update() {
        if (m_isExitCurrentState) {
            //Coding to be continue
            m_isExitCurrentState = false;
            StateMachine_SendMessage(DEFINE.MESSAGE_INIT);
        } else {
            StateMachine_SendMessage(DEFINE.MESSAGE_UPDATE);
        }
    }

    public void StateMachine_Render() {
        if (m_isExitCurrentState == false) {
            StateMachine_SendMessage(DEFINE.MESSAGE_RENDER);
        }
    }

    public void StateMachine_SendMessage(int message) {
        switch (m_iCurrentState) {
            case DEFINE.STATE_LOGO: {
                m_stateLogo.HandleMessage(message);
            }
            break;

            case DEFINE.STATE_SPLASH: {
                m_stateSplash.HandleMessage(message);
            }
            break;

            case DEFINE.STATE_MAINMENU: {
                m_stateMainMenu.HandleMessage(message);
            }
            break;

            case DEFINE.STATE_NEWGAME: {
                m_stateNewGame.HandleMessage(message);
            }break;
                
            case DEFINE.STATE_CONFIRM_MENU: {
                m_statecConfirmMenu.HandleMessage(message);
            }break;

            default:
                break;
        }
    }

    public void SwitchState(int state) {
        m_iCurrentState = state;
        m_isExitCurrentState = true;
        m_iKeyPressAction = 0; // Reset key action
    }

    //------------------------------------------------------------------------//
    //----------------------------------Key event-----------------------------//
    //------------------------------------------------------------------------//
    protected void keyPressed(int keyCode) {
        //System.out.println("Key pess: " + keyCode);
        int ikeyAction = getGameAction(keyCode);
        if (keyCode == Canvas.KEY_NUM2 || ikeyAction == Canvas.UP) {
            this.AddKeyAction(DEFINE.KEY_UP);

        } else if (keyCode == Canvas.KEY_NUM8 || ikeyAction == Canvas.DOWN) {
            this.AddKeyAction(DEFINE.KEY_DOWN);

        } else if (keyCode == Canvas.KEY_NUM4 || ikeyAction == Canvas.LEFT) {
            this.AddKeyAction(DEFINE.KEY_LEFT);

        } else if (keyCode == Canvas.KEY_NUM6 || ikeyAction == Canvas.RIGHT) {
            this.AddKeyAction(DEFINE.KEY_RIGHT);

        } else if (keyCode == Canvas.KEY_NUM5 || ikeyAction == Canvas.FIRE) {
            this.AddKeyAction(DEFINE.KEY_FIRE);
        } else {
            this.AddKeyAction(DEFINE.KEY_SOMETHING);
        }
    }

    protected void keyReleased(int keyCode) {
        //System.out.println("Key release: " + keyCode);
        int ikeyAction = getGameAction(keyCode);
        if (keyCode == Canvas.KEY_NUM2 || ikeyAction == Canvas.UP) {
            this.RemoveKeyAction(DEFINE.KEY_UP);

        } else if (keyCode == Canvas.KEY_NUM8 || ikeyAction == Canvas.DOWN) {
            this.RemoveKeyAction(DEFINE.KEY_DOWN);

        } else if (keyCode == Canvas.KEY_NUM4 || ikeyAction == Canvas.LEFT) {
            this.RemoveKeyAction(DEFINE.KEY_LEFT);

        } else if (keyCode == Canvas.KEY_NUM6 || ikeyAction == Canvas.RIGHT) {
            this.RemoveKeyAction(DEFINE.KEY_RIGHT);

        } else if (keyCode == Canvas.KEY_NUM5 || ikeyAction == Canvas.FIRE) {
            this.RemoveKeyAction(DEFINE.KEY_FIRE);

        } else {
            this.RemoveKeyAction(DEFINE.KEY_SOMETHING);
        }
    }

    protected void pointerPressed(int x, int y) {
        GLOBAL.TOUCH_X = x;
        GLOBAL.TOUCH_Y = y;
        GLOBAL.IS_TOUCH = true;
    }

    protected void pointerReleased(int x, int y) {
        GLOBAL.TOUCH_X = x;
        GLOBAL.TOUCH_Y = y;        
        GLOBAL.IS_TOUCH = false;
    }

    protected void pointerDragged(int x, int y) {
        GLOBAL.TOUCH_X = x;
        GLOBAL.TOUCH_Y = y;
    }   
    
}
